/*
 * MainForm.cpp
 * Authors: 107 <107@mail.ru>
 * License: GPL >=2.0
 *
 * Base user inteface.
 * Have buttons, menus and Scrolled Viewer
 *
 * Provide minimal needed methods to meet all functions from menu.
 * Call backend on some actions when form manipulation needed.
 *
 */

#include "MainForm.h"
#include "FileDialog.h"
#include <math.h>
#include "macros.h"

using namespace Osp::Base;
using namespace Osp::Ui;
using namespace Osp::Graphics;
using namespace Osp::Ui::Controls;
using namespace Osp::Io;


MainForm::MainForm(void) : ScrolledViewer() {
	// init variables
	IsSaved = true;
}

MainForm::~MainForm(void) {
//	this->RemoveAllControls();
}

bool MainForm::Initialize() {
	Form::Construct( FORM_STYLE_NORMAL  |
				     !FORM_STYLE_TITLE  |
				     !FORM_STYLE_INDICATOR |
				     FORM_STYLE_SOFTKEY_0  |
				     FORM_STYLE_SOFTKEY_1  |
				     FORM_STYLE_OPTIONKEY
				     /*| FORM_STYLE_TEXT_TAB*/
				     );
	return true;
}



result MainForm::OnInitializing( void ) {


	result r = E_SUCCESS;
	// Form
	AddOrientationEventListener( *this );
	SetOrientation(ORIENTATION_AUTOMATIC_FOUR_DIRECTION);
	AddTouchEventListener( *this );


	// Create Soft Keys
	SetSoftkeyText( SOFTKEY_0, S( "IDS_OPEN" ) );
	SetSoftkeyText( SOFTKEY_1, S( "IDS_SAVE" ) );
	SetSoftkeyActionId( SOFTKEY_0, ID_SOFTKEY_LEFT );
	SetSoftkeyActionId( SOFTKEY_1, ID_SOFTKEY_RIGHT );
	AddSoftkeyActionListener( SOFTKEY_0, *this );
	AddSoftkeyActionListener( SOFTKEY_1, *this );
	// Create Option Menu
	SetOptionkeyActionId( ID_OPTIONKEY );
	AddOptionkeyActionListener(*this);
	__pOptionMenu = new OptionMenu();
	__pOptionMenu->Construct();

	__pOptionMenu->AddItem( S( "IDS_SAVE_AS" ), ID_OPTIONKEY_SAVE_AS );
	__pOptionMenu->AddItem( S( "IDS_NEW" ), 	ID_OPTIONKEY_NEW );
	__pOptionMenu->AddItem( S( "IDS_LICENSE" ), ID_OPTIONKEY_LICENSE );
	__pOptionMenu->AddItem( S( "IDS_ABOUT" ), 	ID_OPTIONKEY_ABOUT );

	// Add a sub items to the first item in the options menu @ index 0
	/*
	__pOptionMenu->AddSubItem(0, "Sub item1", ID_OPTIONA);
	__pOptionMenu->AddSubItem(0, "Sub item2", ID_OPTIONB);
	*/
	// Register an event listener
	SetOptionkeyActionId( ID_OPTIONKEY );
	__pOptionMenu->AddActionEventListener(*this);
	this->AddControl( *__pOptionMenu );


	return r;
}

// virtual
Osp::Graphics::Canvas * MainForm::GetRealCanvasN ( void ) {
	return IsVisible()?GetCanvasN():null;
};



result MainForm::OnDraw( void ) {
	AppLog(" OnDraw ");
	if ( !IsVisible() || !GetShowState() || GetBounds().height<=1 || GetBounds().width<=1 ) return E_SUCCESS;
	// if ! initilized -> set size
	if ( ! GetCanvasBounds().Equals( GetBounds() ) ) {
		GetCanvasN()->Clear();
		AppLog( "Bounds changed" );
		ScrolledViewer::SetSize ( GetSize() );
	}

	RenderCurrentPosition( true );
}

result MainForm::OnTerminating(void) {
	result r = E_SUCCESS;
	// TODO: Add your termination code here
	return r;
}

// virtual
void MainForm::msg ( const Osp::Base::String title, const Osp::Base::String message ) {
	MessageBox msgbox;
	msgbox.Construct( title, message, MSGBOX_STYLE_OK, 0 );
	int modalresult = 0;
	msgbox.ShowAndWait( modalresult );
}


void MainForm::SetSavedStatus ( bool saved ) {
	String val;
	IsSaved = saved;
	val = saved?S( "IDS_SAVE" ):String( S( "IDS_SAVE" )+"*" );
	SetSoftkeyText( SOFTKEY_1, val );
	AppLog ( "save status %S", val.GetPointer() );
	RequestRedraw( true );
}


void MainForm::Save ( void ) {
	// if !file_name => Save As
	if ( sFileName != "" ) {
		SaveToFile( sFileName );
		SetSavedStatus( true );
	} else {
		AppLog( "Call ON_SAVE_AS" );
		this->SetShowState( false );
		this->sendContainerActionToParent(MainForm::ON_SAVE_AS);
	}
}

void MainForm::CheckUnsaved ( void ) {
	if ( IsSaved ) { return; };
	MessageBox msgbox;
	msgbox.Construct( S( "IDS_FILE_NOT_SAVED" ), S( "IDS_WOULD_LIKE_SAVE" ),
				MSGBOX_STYLE_YESNO, 0);
	int modalresult=0;
	msgbox.ShowAndWait(modalresult);
	if ( modalresult==MSGBOX_RESULT_YES  )	{
		Save();
	} else {
		SetSavedStatus( true );
	}
}


// reactions

void MainForm::OnActionPerformed(const Osp::Ui::Control& source, int actionId) {

	AppLog( "actionId %d", actionId );

	switch(actionId) 	{

	case ID_OPTIONKEY: {
		 __pOptionMenu->SetShowState(true);
         __pOptionMenu->Show();
	}
	break;

	case ID_OPTIONKEY_SAVE_AS: {
		AppLog( "ID optionkey save as" );
		this->sendContainerActionToParent(MainForm::ON_SAVE_AS);
	}
	break;

	case ID_OPTIONKEY_LICENSE: {
		AppLog( "ID optionkey license" );
		CheckUnsaved();
		if ( IsSaved ) {
		LoadFromFile( L"/Res/gpl-3.0.txt" );
		sFileName="";
		}
	}
	break;

	case ID_OPTIONKEY_ABOUT: {
		AppLog( "ID optionkey about" );
		msg( S( "IDS_ABOUT" ), String( S( "IDS_APP_NAME" ) + L" v" + VERSION + L"\n" + S( "IDS_ABOUT_TEXT" ) + L"\n" + S( "IDS_HOME_URL" )) );
	}
	break;

	case ID_OPTIONKEY_NEW: {
		AppLog( "ID optionkey new" );
		CheckUnsaved();
		if ( IsSaved ) Clear();
	}
	break;

	case ID_SOFTKEY_LEFT: {
		AppLog( "ID softkey left" );
		CheckUnsaved();
	    if ( IsSaved ) this->sendContainerActionToParent(MainForm::ON_OPEN_FILE);
	}
	break;

	case ID_SOFTKEY_RIGHT: {
		AppLog( "ID softkey right" );
		Save();
	}
	break;

	default:
		AppLog( "ID default" );
	break;
	}
}



void MainForm::OnOrientationChanged(const Osp::Ui::Control &source, Osp::Ui::OrientationStatus orientationStatus) {
	AppLog ( "orientation changed" );
	ScrolledViewer::SetSize ( GetSize() );
	RenderCurrentPosition( true );
}

void MainForm::OnTouchDoublePressed(const Osp::Ui::Control &source, const Osp::Graphics::Point &currentPosition, const Osp::Ui::TouchEventInfo &touchInfo) {
	// TODO: Add your implementation codes here
}

void MainForm::OnTouchFocusIn(const Osp::Ui::Control &source, const Osp::Graphics::Point &currentPosition, const Osp::Ui::TouchEventInfo &touchInfo) {
	// TODO: Add your implementation codes here
}

void MainForm::OnTouchFocusOut(const Osp::Ui::Control &source, const Osp::Graphics::Point &currentPosition, const Osp::Ui::TouchEventInfo &touchInfo) {
	// TODO: Add your implementation codes here
}

void MainForm::OnTouchLongPressed(const Osp::Ui::Control &source, const Osp::Graphics::Point &currentPosition, const Osp::Ui::TouchEventInfo &touchInfo) {
	// TODO: Add your implementation codes here
}

void MainForm::OnTouchMoved(const Osp::Ui::Control &source, const Osp::Graphics::Point &currentPosition, const Osp::Ui::TouchEventInfo &touchInfo) {


		// touch progress bar
		if ( GetProgressBounds().Contains( currentPosition ) ) {
				OnProgressTouch ( currentPosition.y );
			return;
		};

		// else editor move
		unsigned int speed = (currentPosition.y - y) / 30; // 20 - maybe use LineHeihg here
//		AppLog( "speed = %d, delta=%d", currentPosition.y - y, speed );

		// scroll my edit
		if ( 0 == y ) { y = touchInfo.GetStartPosition().y; };
		if ( currentPosition.y > y ) {
//			AppLog( "move down" );
			Scroll( -1 );
		}
		if ( currentPosition.y < y ) {
//			AppLog( "move up" );
			Scroll( 1 );
		}
		y = currentPosition.y;

}

void MainForm::OnTouchPressed(const Osp::Ui::Control &source, const Osp::Graphics::Point &currentPosition, const Osp::Ui::TouchEventInfo &touchInfo) {
	touch=currentPosition;

}

void MainForm::OnTouchReleased(const Osp::Ui::Control &source, const Osp::Graphics::Point &currentPosition, const Osp::Ui::TouchEventInfo &touchInfo) {


	if ( ! this->IsVisible() ) {
		return;
	}


	if ( currentPosition != touch ) {
		// this is move
		return ;
	}

	AppLog ( "touch released" );

	// touch progress bar
	if ( GetProgressBounds().Contains( currentPosition ) ) {
			OnProgressTouch ( currentPosition.y );
		return;
	};

	// touch editor
	this->sendContainerActionToParent( MainForm::ON_EDITOR_OPEN );

}

void MainForm::OnTextValueChangeCanceled(const Osp::Ui::Control &source) {

}

void MainForm::OnTextValueChanged(const Osp::Ui::Control &source) {

}
